/*
 * Copyright (c) 2023 iQi.Co.Ltd. All rights reserved.
 */
 
using IQIGame.Onigao.Framework;
using System.Collections.Generic;
using System.Linq;
using System;
using NetProtocol.Enum;

namespace NetProtocol.POD {

	/// <summary>
	/// 
	/// module : structs_internal
	/// </summary>
	public class TestPOD : IPOD 
    {
        public readonly static Func<TestPOD> FACTORY = () => new TestPOD();
		public static Func<TestPOD> DynamicFactory = FACTORY;
        
		/*-- members --*/
		/// <summary>
        /// 
        /// </summary>
        private List<TestPOD1> m_pod1List;
		/// <summary>
        /// 
        /// </summary>
        private Dictionary<TestPOD1, int> m_pod1iMap;
		/// <summary>
        /// 
        /// </summary>
        private Dictionary<int, TestPOD1> m_ipod1Map;
		/// <summary>
        /// 
        /// </summary>
        private Dictionary<TestPOD1, TestPOD2> m_pod1pod2Map;
		/// <summary>
        /// 
        /// </summary>
		public uint a1;
		/// <summary>
        /// 
        /// </summary>
		public ushort a2;
		/// <summary>
        /// 
        /// </summary>
		public byte a3;
		/// <summary>
        /// 
        /// </summary>
		public TestPOD1 pod1;
		/// <summary>
        /// 
        /// </summary>
        private Dictionary<uint, TestPOD1> m_a4;
		/// <summary>
        /// 
        /// </summary>
        private Dictionary<TestPOD1, uint> m_a5;
		/// <summary>
        /// 
        /// </summary>
        private Dictionary<ushort, TestPOD1> m_a6;
		/// <summary>
        /// 
        /// </summary>
        private Dictionary<TestPOD1, ushort> m_a7;
		/// <summary>
        /// 
        /// </summary>
        private Dictionary<byte, TestPOD1> m_a8;
		/// <summary>
        /// 
        /// </summary>
        private Dictionary<TestPOD1, byte> m_a9;
		/// <summary>
        /// 
        /// </summary>
        private List<uint> m_a10;
		/// <summary>
        /// 
        /// </summary>
        private List<ushort> m_a11;
		/// <summary>
        /// 
        /// </summary>
        private List<byte> m_a12;
		/// <summary>
        /// 
        /// </summary>
		public byte[] a13;
		/// <summary>
        /// 
        /// </summary>
        private List<byte[]> m_a14;
		/// <summary>
        /// 
        /// </summary>
        private Dictionary<int, byte[]> m_a15;
		/// <summary>
        /// 
        /// </summary>
		public sbyte a16;
		/// <summary>
        /// 
        /// </summary>
        private Dictionary<sbyte, int> m_a17;
		/// <summary>
        /// 
        /// </summary>
        private Dictionary<int, sbyte> m_a18;
		
		
        public List<TestPOD1> pod1List
        {
            get
            {
                if(m_pod1List == null)
                {
                    m_pod1List = new();
                }
                return m_pod1List;
            }
            private set => m_pod1List = value;
        }
        public List<TestPOD1> unsafe_pod1List
        {
        	get => m_pod1List;
        	set => m_pod1List = value;
        }
        public Dictionary<TestPOD1, int> pod1iMap
        {
            get
            {
                if(m_pod1iMap == null)
                {
                    m_pod1iMap = new();
                }
                return m_pod1iMap;
            }
            private set => m_pod1iMap = value;
        }
        public Dictionary<TestPOD1, int> unsafe_pod1iMap
        {
        	get => m_pod1iMap;
        	set => m_pod1iMap = value;
        }
        public Dictionary<int, TestPOD1> ipod1Map
        {
            get
            {
                if(m_ipod1Map == null)
                {
                    m_ipod1Map = new();
                }
                return m_ipod1Map;
            }
            private set => m_ipod1Map = value;
        }
        public Dictionary<int, TestPOD1> unsafe_ipod1Map
        {
        	get => m_ipod1Map;
        	set => m_ipod1Map = value;
        }
        public Dictionary<TestPOD1, TestPOD2> pod1pod2Map
        {
            get
            {
                if(m_pod1pod2Map == null)
                {
                    m_pod1pod2Map = new();
                }
                return m_pod1pod2Map;
            }
            private set => m_pod1pod2Map = value;
        }
        public Dictionary<TestPOD1, TestPOD2> unsafe_pod1pod2Map
        {
        	get => m_pod1pod2Map;
        	set => m_pod1pod2Map = value;
        }
        public Dictionary<uint, TestPOD1> a4
        {
            get
            {
                if(m_a4 == null)
                {
                    m_a4 = new();
                }
                return m_a4;
            }
            private set => m_a4 = value;
        }
        public Dictionary<uint, TestPOD1> unsafe_a4
        {
        	get => m_a4;
        	set => m_a4 = value;
        }
        public Dictionary<TestPOD1, uint> a5
        {
            get
            {
                if(m_a5 == null)
                {
                    m_a5 = new();
                }
                return m_a5;
            }
            private set => m_a5 = value;
        }
        public Dictionary<TestPOD1, uint> unsafe_a5
        {
        	get => m_a5;
        	set => m_a5 = value;
        }
        public Dictionary<ushort, TestPOD1> a6
        {
            get
            {
                if(m_a6 == null)
                {
                    m_a6 = new();
                }
                return m_a6;
            }
            private set => m_a6 = value;
        }
        public Dictionary<ushort, TestPOD1> unsafe_a6
        {
        	get => m_a6;
        	set => m_a6 = value;
        }
        public Dictionary<TestPOD1, ushort> a7
        {
            get
            {
                if(m_a7 == null)
                {
                    m_a7 = new();
                }
                return m_a7;
            }
            private set => m_a7 = value;
        }
        public Dictionary<TestPOD1, ushort> unsafe_a7
        {
        	get => m_a7;
        	set => m_a7 = value;
        }
        public Dictionary<byte, TestPOD1> a8
        {
            get
            {
                if(m_a8 == null)
                {
                    m_a8 = new();
                }
                return m_a8;
            }
            private set => m_a8 = value;
        }
        public Dictionary<byte, TestPOD1> unsafe_a8
        {
        	get => m_a8;
        	set => m_a8 = value;
        }
        public Dictionary<TestPOD1, byte> a9
        {
            get
            {
                if(m_a9 == null)
                {
                    m_a9 = new();
                }
                return m_a9;
            }
            private set => m_a9 = value;
        }
        public Dictionary<TestPOD1, byte> unsafe_a9
        {
        	get => m_a9;
        	set => m_a9 = value;
        }
        public List<uint> a10
        {
            get
            {
                if(m_a10 == null)
                {
                    m_a10 = new();
                }
                return m_a10;
            }
            private set => m_a10 = value;
        }
        public List<uint> unsafe_a10
        {
        	get => m_a10;
        	set => m_a10 = value;
        }
        public List<ushort> a11
        {
            get
            {
                if(m_a11 == null)
                {
                    m_a11 = new();
                }
                return m_a11;
            }
            private set => m_a11 = value;
        }
        public List<ushort> unsafe_a11
        {
        	get => m_a11;
        	set => m_a11 = value;
        }
        public List<byte> a12
        {
            get
            {
                if(m_a12 == null)
                {
                    m_a12 = new();
                }
                return m_a12;
            }
            private set => m_a12 = value;
        }
        public List<byte> unsafe_a12
        {
        	get => m_a12;
        	set => m_a12 = value;
        }
        public List<byte[]> a14
        {
            get
            {
                if(m_a14 == null)
                {
                    m_a14 = new();
                }
                return m_a14;
            }
            private set => m_a14 = value;
        }
        public List<byte[]> unsafe_a14
        {
        	get => m_a14;
        	set => m_a14 = value;
        }
        public Dictionary<int, byte[]> a15
        {
            get
            {
                if(m_a15 == null)
                {
                    m_a15 = new();
                }
                return m_a15;
            }
            private set => m_a15 = value;
        }
        public Dictionary<int, byte[]> unsafe_a15
        {
        	get => m_a15;
        	set => m_a15 = value;
        }
        public Dictionary<sbyte, int> a17
        {
            get
            {
                if(m_a17 == null)
                {
                    m_a17 = new();
                }
                return m_a17;
            }
            private set => m_a17 = value;
        }
        public Dictionary<sbyte, int> unsafe_a17
        {
        	get => m_a17;
        	set => m_a17 = value;
        }
        public Dictionary<int, sbyte> a18
        {
            get
            {
                if(m_a18 == null)
                {
                    m_a18 = new();
                }
                return m_a18;
            }
            private set => m_a18 = value;
        }
        public Dictionary<int, sbyte> unsafe_a18
        {
        	get => m_a18;
        	set => m_a18 = value;
        }
		
		/*-- constructors --*/
		public TestPOD() {}
		public TestPOD(List<TestPOD1> pod1List, Dictionary<TestPOD1, int> pod1iMap, Dictionary<int, TestPOD1> ipod1Map, Dictionary<TestPOD1, TestPOD2> pod1pod2Map, uint a1, ushort a2, byte a3, TestPOD1 pod1, Dictionary<uint, TestPOD1> a4, Dictionary<TestPOD1, uint> a5, Dictionary<ushort, TestPOD1> a6, Dictionary<TestPOD1, ushort> a7, Dictionary<byte, TestPOD1> a8, Dictionary<TestPOD1, byte> a9, List<uint> a10, List<ushort> a11, List<byte> a12, byte[] a13, List<byte[]> a14, Dictionary<int, byte[]> a15, sbyte a16, Dictionary<sbyte, int> a17, Dictionary<int, sbyte> a18) {
			this.m_pod1List = pod1List;
			this.m_pod1iMap = pod1iMap;
			this.m_ipod1Map = ipod1Map;
			this.m_pod1pod2Map = pod1pod2Map;
			this.a1 = a1;
			this.a2 = a2;
			this.a3 = a3;
			this.pod1 = pod1;
			this.m_a4 = a4;
			this.m_a5 = a5;
			this.m_a6 = a6;
			this.m_a7 = a7;
			this.m_a8 = a8;
			this.m_a9 = a9;
			this.m_a10 = a10;
			this.m_a11 = a11;
			this.m_a12 = a12;
			this.a13 = a13;
			this.m_a14 = a14;
			this.m_a15 = a15;
			this.a16 = a16;
			this.m_a17 = a17;
			this.m_a18 = a18;
		}
		  public void Serial(SOutputStream _out) {
                if(m_pod1List != default) {
                    _out.WriteByte(2);
                    _out.Write_list_pod(m_pod1List);
                }
                if(m_pod1iMap != default) {
                    _out.WriteByte(3);
                    _out.Write_map_pod_int(m_pod1iMap);
                }
                if(m_ipod1Map != default) {
                    _out.WriteByte(4);
                    _out.Write_map_int_pod(m_ipod1Map);
                }
                if(m_pod1pod2Map != default) {
                    _out.WriteByte(5);
                    _out.Write_map_pod_pod(m_pod1pod2Map);
                }
                if(a1 != default) {
                    _out.WriteByte(6);
                    _out.Write_uint(a1);
                }
                if(a2 != default) {
                    _out.WriteByte(7);
                    _out.Write_ushort(a2);
                }
                if(a3 != default) {
                    _out.WriteByte(8);
                    _out.Write_ubyte(a3);
                }
                if(pod1 != default) {
                    _out.WriteByte(1);
                    _out.Write_pod(pod1);
                }
                if(m_a4 != default) {
                    _out.WriteByte(9);
                    _out.Write_map_uint_pod(m_a4);
                }
                if(m_a5 != default) {
                    _out.WriteByte(10);
                    _out.Write_map_pod_uint(m_a5);
                }
                if(m_a6 != default) {
                    _out.WriteByte(11);
                    _out.Write_map_ushort_pod(m_a6);
                }
                if(m_a7 != default) {
                    _out.WriteByte(12);
                    _out.Write_map_pod_ushort(m_a7);
                }
                if(m_a8 != default) {
                    _out.WriteByte(13);
                    _out.Write_map_ubyte_pod(m_a8);
                }
                if(m_a9 != default) {
                    _out.WriteByte(14);
                    _out.Write_map_pod_ubyte(m_a9);
                }
                if(m_a10 != default) {
                    _out.WriteByte(15);
                    _out.Write_list_uint(m_a10);
                } 
                if(m_a11 != default) {
                    _out.WriteByte(16);
                    _out.Write_list_ushort(m_a11);
                } 
                if(m_a12 != default) {
                    _out.WriteByte(17);
                    _out.Write_list_ubyte(m_a12);
                } 
                if(a13 != default) {
                    _out.WriteByte(18);
                    _out.Write_bytes(a13);
                }
                if(m_a14 != default) {
                    _out.WriteByte(19);
                    _out.Write_list_bytes(m_a14);
                } 
                if(m_a15 != default) {
                    _out.WriteByte(20);
                    _out.Write_map_int_bytes(m_a15);
                }
                if(a16 != default) {
                    _out.WriteByte(21);
                    _out.Write_byte(a16);
                }
                if(m_a17 != default) {
                    _out.WriteByte(123);
                    _out.Write_map_byte_int(m_a17);
                }
                if(m_a18 != default) {
                    _out.WriteByte(124);
                    _out.Write_map_int_byte(m_a18);
                }
        }
            
        public void UnSerial(SInputStream _in) {
            while (_in.HasRemaining())
            {
                int _key = _in.ReadByte();
                switch (_key)
                {
                    case 2:
                        m_pod1List = _in.Read_list_pod<TestPOD1>(TestPOD1.DynamicFactory);
                        break;
                    case 3:
                        m_pod1iMap = _in.Read_map_pod_int<TestPOD1>(TestPOD1.DynamicFactory);
                        break;
                    case 4:
                        m_ipod1Map = _in.Read_map_int_pod<TestPOD1>(TestPOD1.DynamicFactory);
                        break;
                    case 5:
                        m_pod1pod2Map = _in.Read_map_pod_pod<TestPOD1, TestPOD2>(TestPOD1.DynamicFactory, TestPOD2.DynamicFactory);
                        break;
                    case 6:
                        a1 = _in.Read_uint();
                        break;
                    case 7:
                        a2 = _in.Read_ushort();
                        break;
                    case 8:
                        a3 = _in.Read_ubyte();
                        break;
                    case 1:
                        pod1 = _in.Read_pod<TestPOD1>(TestPOD1.DynamicFactory);
                        break;
                    case 9:
                        m_a4 = _in.Read_map_uint_pod<TestPOD1>(TestPOD1.DynamicFactory);
                        break;
                    case 10:
                        m_a5 = _in.Read_map_pod_uint<TestPOD1>(TestPOD1.DynamicFactory);
                        break;
                    case 11:
                        m_a6 = _in.Read_map_ushort_pod<TestPOD1>(TestPOD1.DynamicFactory);
                        break;
                    case 12:
                        m_a7 = _in.Read_map_pod_ushort<TestPOD1>(TestPOD1.DynamicFactory);
                        break;
                    case 13:
                        m_a8 = _in.Read_map_ubyte_pod<TestPOD1>(TestPOD1.DynamicFactory);
                        break;
                    case 14:
                        m_a9 = _in.Read_map_pod_ubyte<TestPOD1>(TestPOD1.DynamicFactory);
                        break;
                    case 15:
                        m_a10 = _in.Read_list_uint();
                        break;
                    case 16:
                        m_a11 = _in.Read_list_ushort();
                        break;
                    case 17:
                        m_a12 = _in.Read_list_ubyte();
                        break;
                    case 18:
                        a13 = _in.Read_bytes();
                        break;
                    case 19:
                        m_a14 = _in.Read_list_bytes();
                        break;
                    case 20:
                        m_a15 = _in.Read_map_int_bytes();
                        break;
                    case 21:
                        a16 = _in.Read_byte();
                        break;
                    case 123:
                        m_a17 = _in.Read_map_byte_int();
                        break;
                    case 124:
                        m_a18 = _in.Read_map_int_byte();
                        break;
                    default: _in.SkipBinary();break;
                }
            }
        }
		
		public TestPOD Clone() {
            TestPOD o = DynamicFactory();
            if (m_pod1List != null) {
                o.m_pod1List = m_pod1List.ConvertAll(o => o?.Clone());
            }
            if (m_pod1iMap != null) {
                o.m_pod1iMap = new ();
				m_pod1iMap.ToList().ForEach(kv => o.m_pod1iMap.Add(kv.Key?.Clone(), kv.Value));
            }
            if (m_ipod1Map != null) {
                o.m_ipod1Map = new ();
				m_ipod1Map.ToList().ForEach(kv => o.m_ipod1Map.Add(kv.Key, kv.Value?.Clone()));
            }
            if (m_pod1pod2Map != null) {
                o.m_pod1pod2Map = new ();
				m_pod1pod2Map.ToList().ForEach(kv => o.m_pod1pod2Map.Add(kv.Key?.Clone(), kv.Value?.Clone()));
            }
            o.a1 = a1;
            o.a2 = a2;
            o.a3 = a3;
            if (pod1 != null) {
                o.pod1 = pod1.Clone();
            }
            if (m_a4 != null) {
                o.m_a4 = new ();
				m_a4.ToList().ForEach(kv => o.m_a4.Add(kv.Key, kv.Value?.Clone()));
            }
            if (m_a5 != null) {
                o.m_a5 = new ();
				m_a5.ToList().ForEach(kv => o.m_a5.Add(kv.Key?.Clone(), kv.Value));
            }
            if (m_a6 != null) {
                o.m_a6 = new ();
				m_a6.ToList().ForEach(kv => o.m_a6.Add(kv.Key, kv.Value?.Clone()));
            }
            if (m_a7 != null) {
                o.m_a7 = new ();
				m_a7.ToList().ForEach(kv => o.m_a7.Add(kv.Key?.Clone(), kv.Value));
            }
            if (m_a8 != null) {
                o.m_a8 = new ();
				m_a8.ToList().ForEach(kv => o.m_a8.Add(kv.Key, kv.Value?.Clone()));
            }
            if (m_a9 != null) {
                o.m_a9 = new ();
				m_a9.ToList().ForEach(kv => o.m_a9.Add(kv.Key?.Clone(), kv.Value));
            }
            if (m_a10 != null) {
                o.m_a10 = new (m_a10);
            }
            if (m_a11 != null) {
                o.m_a11 = new (m_a11);
            }
            if (m_a12 != null) {
                o.m_a12 = new (m_a12);
            }
            if (a13 != null) {
                o.a13 = (byte[])a13.Clone();
            }
            if (m_a14 != null) {
                o.m_a14 = m_a14.ConvertAll(o => (byte[])o?.Clone());
            }
            if (m_a15 != null) {
                o.m_a15 = new ();
				m_a15.ToList().ForEach(kv => o.m_a15.Add(kv.Key, (byte[])kv.Value?.Clone()));
            }
            o.a16 = a16;
            if (m_a17 != null) {
                o.m_a17 = new (m_a17);
            }
            if (m_a18 != null) {
                o.m_a18 = new (m_a18);
            }
            return o;
        }
        
        public void Clear() {
            m_pod1List = default;
            m_pod1iMap = default;
            m_ipod1Map = default;
            m_pod1pod2Map = default;
            a1 = default;
            a2 = default;
            a3 = default;
            pod1 = default;
            m_a4 = default;
            m_a5 = default;
            m_a6 = default;
            m_a7 = default;
            m_a8 = default;
            m_a9 = default;
            m_a10 = default;
            m_a11 = default;
            m_a12 = default;
            a13 = default;
            m_a14 = default;
            m_a15 = default;
            a16 = default;
            m_a17 = default;
            m_a18 = default;
        }
		
        public override string ToString() {
			string str = "";
			str += "TestPOD [";
			str += "pod1List=";
			str += m_pod1List.ToString<TestPOD1>();
			str += ", pod1iMap=";
			str += m_pod1iMap.ToString<TestPOD1, int>();
			str += ", ipod1Map=";
			str += m_ipod1Map.ToString<int, TestPOD1>();
			str += ", pod1pod2Map=";
			str += m_pod1pod2Map.ToString<TestPOD1, TestPOD2>();
			str += ", a1=";
			str += a1;
			str += ", a2=";
			str += a2;
			str += ", a3=";
			str += a3;
			str += ", pod1=";
			str += pod1;
			str += ", a4=";
			str += m_a4.ToString<uint, TestPOD1>();
			str += ", a5=";
			str += m_a5.ToString<TestPOD1, uint>();
			str += ", a6=";
			str += m_a6.ToString<ushort, TestPOD1>();
			str += ", a7=";
			str += m_a7.ToString<TestPOD1, ushort>();
			str += ", a8=";
			str += m_a8.ToString<byte, TestPOD1>();
			str += ", a9=";
			str += m_a9.ToString<TestPOD1, byte>();
			str += ", a10=";
			str += m_a10.ToString<uint>();
			str += ", a11=";
			str += m_a11.ToString<ushort>();
			str += ", a12=";
			str += m_a12.ToString<byte>();
			str += ", a13=";
			str += a13;
			str += ", a14=";
			str += m_a14.ToString<byte[]>();
			str += ", a15=";
			str += m_a15.ToString<int, byte[]>();
			str += ", a16=";
			str += a16;
			str += ", a17=";
			str += m_a17.ToString<sbyte, int>();
			str += ", a18=";
			str += m_a18.ToString<int, sbyte>();
			str += "]";
			return str;
		}
		
	}
}